﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_OCF_Parser.h".
//-------------------------------------------------------------------

#ifndef _UXS_CREATE_META_OBJECT_FUNC_H
#define _UXS_CREATE_META_OBJECT_FUNC_H

#pragma once

//#define _M_CEE_SAFE

#include "../../stl_core/ux_stl_core.h"
#include "../../stl_ext/OS/OSPlatform.h"
#include "../../stl_ext/Types/TVariant.h"
#include "../../stl_ext/Deprecated/TTree.h"

namespace UX_STL
{
namespace UXMetaTypes
{
	using namespace UXTypes;
	using namespace UXTypesExt;
	using namespace UXMath;

	class IMetaBaseType;
}	// UXMetaTypes

	using namespace UXTypes;



	// helpers macro
#undef  UX_DECLARE_META_OBJECT
#define UX_DECLARE_META_OBJECT( _type ) \
	UXMetaTypes::IMetaBaseType * CreateMetaObject(uni_c_string pName, usize uOffset, usize uSize, _type& obj)


#undef  UX_CREATE_META_OBJECT
#define UX_CREATE_META_OBJECT( _type, _meta_class ) \
	UXMetaTypes::IMetaBaseType * CreateMetaObject(uni_c_string pName, usize uOffset, usize uSize, _type& obj) \
	{ \
		return new UXMetaTypes::CMetaObjectType( pName, uOffset, _meta_class.GetObjectType() ); \
	}

#undef  UX_ENUM_META_OBJECT
#define UX_ENUM_META_OBJECT( _type ) \
	template <> \
	inline UXMetaTypes::IMetaBaseType * CreateMetaObjectTempl<_type>(uni_c_string pName, usize uOffset, usize uSize) \
	{ \
		return CreateMetaObjectTempl< NearInt::Signed<_type>::type >( pName, uOffset, uSize ); \
	}

#undef  UX_DECLARE_META_TYPEDEF
#define UX_DECLARE_META_TYPEDEF( _type, _base_type ) \
	UXMetaTypes::IMetaBaseType * CreateMetaObject(uni_c_string pName, usize uOffset, usize uSize, _type& obj) \
	{ \
		STATIC_ASSERTE( sizeof(_type) == sizeof(_base_type) ); \
		return UX_STL::CreateMetaObject( pName, uOffset, uSize, (_base_type &) obj ); \
	}

	


	// override this function while add new meta object

	template <typename T>
	inline UXMetaTypes::IMetaBaseType * CreateMetaObject(uni_c_string pName, usize uOffset, usize uSize, T& obj)
	{
		STATIC_WARNING( "unknown type" );
		return null;
	}

	
	// override this function while add new meta object

	template <typename T>
	inline UXMetaTypes::IMetaBaseType * CreateMetaObjectTempl(uni_c_string pName, usize uOffset, usize uSize)
	{
		T	temp;
		return CreateMetaObject( pName, uOffset, uSize, temp );
	}


	template <usize Size>
	inline UXMetaTypes::IMetaBaseType * __CreateNearTypeMetaObj(uni_c_string pName, usize uOffset, usize uSize)
	{
		STATIC_WARNING( "unknown type" );
		return null;
	}


	
	UX_DECLARE_META_OBJECT( bool );
	UX_DECLARE_META_OBJECT( int8 );
	UX_DECLARE_META_OBJECT( int16 );
	UX_DECLARE_META_OBJECT( int32 );
	UX_DECLARE_META_OBJECT( int64 );
	UX_DECLARE_META_OBJECT( float );
	UX_DECLARE_META_OBJECT( double );
	UX_DECLARE_META_OBJECT( float32_t );
	UX_DECLARE_META_OBJECT( float64_t );
	//UX_DECLARE_META_OBJECT( TVariant );
	

#define _CREATE_DEF_META_OBJECT( _type ) \
	template <> \
	inline UXMetaTypes::IMetaBaseType * CreateMetaObjectTempl<_type>(uni_c_string pName, usize uOffset, usize uSize) \
	{ \
		_type	temp; \
		return CreateMetaObject( pName, uOffset, uSize, temp ); \
	}

	_CREATE_DEF_META_OBJECT( bool );
	_CREATE_DEF_META_OBJECT( int8 );
	_CREATE_DEF_META_OBJECT( int16 );
	_CREATE_DEF_META_OBJECT( int32 );
	_CREATE_DEF_META_OBJECT( int64 );
	_CREATE_DEF_META_OBJECT( float );
	_CREATE_DEF_META_OBJECT( double );
	_CREATE_DEF_META_OBJECT( float32_t );
	_CREATE_DEF_META_OBJECT( float64_t );
	//_CREATE_DEF_META_OBJECT( TVariant );

#undef  _CREATE_DEF_META_OBJECT
	
	
	
#define _CREATE_DEF_META_OBJECT( _type ) \
	template <> \
	inline UXMetaTypes::IMetaBaseType * __CreateNearTypeMetaObj<sizeof(_type)>(uni_c_string pName, usize uOffset, usize uSize) \
	{ \
		return CreateMetaObjectTempl<_type>( pName, uOffset, uSize ); \
	}
	
	_CREATE_DEF_META_OBJECT( int8  );
	_CREATE_DEF_META_OBJECT( int16 );
	_CREATE_DEF_META_OBJECT( int32 );
	_CREATE_DEF_META_OBJECT( int64 );

#undef  _CREATE_DEF_META_OBJECT

	
#define _CREATE_DEF_META_OBJECT( _type ) \
	template <> \
	inline UXMetaTypes::IMetaBaseType * CreateMetaObjectTempl<_type>(uni_c_string pName, usize uOffset, usize uSize) \
	{ \
		return __CreateNearTypeMetaObj<sizeof(_type)>( pName, uOffset, uSize ); \
	}
	
	_CREATE_DEF_META_OBJECT( uint8  );
	_CREATE_DEF_META_OBJECT( uint16 );
	_CREATE_DEF_META_OBJECT( uint32 );
	_CREATE_DEF_META_OBJECT( uint64 );
	
#undef  _CREATE_DEF_META_OBJECT

//-------------------------------------------------------------------
	
}	// UX_STL

#endif	// _UXS_CREATE_META_OBJECT_FUNC_H